package com.shengzhe.ostudent.utils.security;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.shengzhe.ostudent.common.exception.OsException;
import com.shengzhe.ostudent.utils.request.RequestLocalHolder;
import com.shengzhe.ostudent.utils.result.E;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class JwtUtils {

    /**
     * 用于token签名
     */
    private static final String signature = "ChangeClass";

    /**
     * 制作一个token
     */
    public static String createToken(Map<String, String> map) {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DATE, 7);//设置默认七天过期
        JWTCreator.Builder builder = JWT.create();
        // 遍历map，将里面的值设置到token中
        map.forEach(builder::withClaim);
        return builder.withExpiresAt(instance.getTime())
                .sign(Algorithm.HMAC512(signature));
    }

    public static String createToken(Long userId) {
        Map<String, String> map = new HashMap<String, String>() {{
            put("userId", String.valueOf(userId));
            put("timestamp", String.valueOf(System.currentTimeMillis()));
        }};

        return createToken(map);
    }


    /**
     * 解析token合法性
     */
    public static void checkToken(String token) throws OsException {
        if (token == null) {
            throw new OsException(E.USER_CODE_N3);
        }
        try {
            JWT.require(Algorithm.HMAC512(signature)).build().verify(token);
        } catch (Exception e) {
            throw new OsException(E.USER_CODE_N13);
        }

    }

    /**
     * 获取token信息的方法
     */
    public static DecodedJWT getTokenInfo(String token) {
        return JWT.require(Algorithm.HMAC512(signature)).build().verify(token);
    }

    /**
     * 通过token获取用户id
     *
     * @param token token信息
     * @author xuan
     * @since 2022/3/7 15:20
     */
    public static String getUserIdByToken(String token) {
        DecodedJWT JWT;
        String userId;
        try {
            JWT = JwtUtils.getTokenInfo(token);
            userId = JWT
                    .getClaims()
                    .get("userId")
                    .asString();
        } catch (Exception e) {
            return null;
        }

        //从token中提取用户id
        return userId;
    }

    public static Long getUserId() {
        HttpServletRequest request = RequestLocalHolder.getHttpServletRequest();
        String userId = getUserIdByToken(request.getHeader("token"));
        if (Objects.isNull(userId)) {
            return 0L;
        }
        return Long.valueOf(userId);
    }

}
